/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sopra09.lv6659438.controller.eintragAuswaehlen;

import java.util.List;
import javax.naming.InitialContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import sopra09.lv6659438.logik.eintragAuswaehlen.EintragAuswaehlenALLocal;
import sopra09.lv6659438.objekte.Autor;
import sopra09.lv6659438.objekte.Buch;
import sopra09.lv6659438.objekte.Zeitschrift;

/**
 * Sucht anhand der vom Nutzer eingegebenen Daten einen oder mehrere passende
 * Literatureinträge, legt die Ergebnisliste im Session Scope ab und gibt an den
 * übergeordneten Anwendungsfall (in diesem Fall nur 'Eintrag Loeschen') zurück.
 * @author TJ
 */
public class EintragAuswaehlenUCA extends de.fernunihagen.informatik.pi3.struts.UseCaseAction {
    
    /* forward name="success" path="" */

    private final static String INITIALISIERE_ERGEBNIS_ANZEIGEN = "initialisiereErgebnisAnzeigen";
    private final static String ERGEBNIS_ANZEIGEN = "ergebnisAnzeigen";
    private final static String SUCHKRITERIEN_EINGEBEN_ANZEIGEN = "suchkriterienEingebenAnzeigen";
    private final static String SELEKTIERTEN_EINTRAG_LOESCHEN = "selektiertenEintragLoeschen";    
    
    /**
     * Räumt den Session Scope auf und prüft ob überhaupt ein Literatureintrag
     * in der Datenbank vorhanden ist.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
    public ActionForward starteEintragAuswaehlen(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        log.warn("starteEintragAuswaehlen(...) beginnt");

        // session scope aufräumen
        request.getSession().setAttribute("selektiertesItem", null);
        log.warn("das Attribut 'selektiertesItem' wurde vorsorglich auf null gesetzt, da es" +
                "noch ein vorher selektiertes Item enthalten kann");

        // prüfen ob eintrag vorhanden ist
        InitialContext ic = new InitialContext();
        EintragAuswaehlenALLocal eintragAuswaehlen =
                (EintragAuswaehlenALLocal)ic.lookup("java:comp/env/ejb/eintragAuswaehlen");

        boolean eintragVorhanden = eintragAuswaehlen.istEintragVorhanden();
        log.warn("eintragVorhanden ist: " + eintragVorhanden);

        if (eintragVorhanden){
            log.warn("Da eintragVorhanden " + eintragVorhanden + " ist, wird an " +
                    mapping.findForward(SUCHKRITERIEN_EINGEBEN_ANZEIGEN).getPath() + " weitergeleitet");

            request.getSession().setAttribute("AWF", "Eintrag auswählen");
            request.getSession().setAttribute("AA", "Suchkriterien eingeben");

            return mapping.findForward(SUCHKRITERIEN_EINGEBEN_ANZEIGEN);

         } else {
            log.warn("Da eintragVorhanden " + eintragVorhanden + " ist, wird an " +
                   mapping.getInputForward().getPath() + " weitergeleitet und eine Fehlermeldung ausgegeben");
           ActionMessages fehler = new ActionMessages();
           fehler.add("keinEintragVorhanden", new ActionMessage("fehlermeldung.istEintragVorhanden"));
           saveErrors(request, fehler);
           return mapping.getInputForward();
         }
    }

    /**
     * Sucht anhand der vom Nutzer eingegebenen Suchkriterien passende Literatureinträge
     * und legt die Ergebnisliste im Session Scope ab.
    * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
    public ActionForward suche(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("suche(...) beginnt");

        // session scope aufräumen
        request.getSession().setAttribute("Ergebnisliste", null);
        log.warn("das Attribut 'Ergebnisliste' wurde vorsorglich auf null gesetzt, da es" +
            "noch eine vorher übergebene Liste enthalten kann");

        // suchkriterien auslesen und loggen
        SuchkriterienEingebenAF vf = (SuchkriterienEingebenAF) form;
         log.warn("typ ist: " + vf.getTyp());
         log.warn("titel ist: " +  vf.getTitel());
         log.warn("autor ist: " +  vf.getAutor());
         log.warn("jahr ist: " +  vf.getJahr());

         //anwendungslogik mit suche beauftragen
        InitialContext ic = new InitialContext();
        EintragAuswaehlenALLocal listHandler =
                (EintragAuswaehlenALLocal)ic.lookup("java:comp/env/ejb/eintragAuswaehlen");

        List ergebnisListe = (List)listHandler.sucheEintrag(vf.getTyp(), vf.getTitel(), vf.getAutor(), vf.getJahr());

        log.warn("ergebnisListe ist vom Typ: " + ergebnisListe.getClass().getName());
        log.warn("ergebnisListe ist leer?  " + ergebnisListe.isEmpty());
        log.warn("ergebnisListe hat: " + ergebnisListe.size() + "Elemente");

        if (!ergebnisListe.isEmpty()){
            log.warn("Das erste Elemente von ergebnisListe ist vom Typ: " + ergebnisListe.get(0).getClass().getName());
            log.warn("Das letze Elemente von ergebnisListe ist vom Typ: " + ergebnisListe.get(ergebnisListe.size()-1).getClass().getName());

            //ergebnisliste im session scope ablegen
            request.getSession().setAttribute("Ergebnisliste", ergebnisListe);

            log.warn("da (!ergebnisListe.isEmpty()) " + (!ergebnisListe.isEmpty()) + " ist, " +
                    "wird an " +  mapping.findForward(INITIALISIERE_ERGEBNIS_ANZEIGEN).getPath() + " weitergeleitet.");

            return mapping.findForward(INITIALISIERE_ERGEBNIS_ANZEIGEN);

        } else {

            log.warn("da (!ergebnisListe.isEmpty()) " + (!ergebnisListe.isEmpty()) + " ist, " +
                    "wird an " +  mapping.getInputForward().getPath() + " weitergeleitet " +
                    "und eine Fehlermeldung ausgegeben.");

            ActionMessages fehler = new ActionMessages();
            fehler.add("keinEintragGefunden", new ActionMessage("fehlermeldung.sucheEintrag"));
            saveErrors(request, fehler);

            return mapping.getInputForward();
        }
    }

    /**
     * Anzeige des Suchergebnisses initialisieren
    * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
    public ActionForward initialisiereErgebnisAnzeigen(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
            log.warn("initialisiereErgebnisAnzeigen(...) beginnt");

            // session scope aufräumen
            request.getSession().setAttribute("AWF", "Eintrag auswählen");
            request.getSession().setAttribute("AA", "Ergebnis anzeigen");

            request.getSession().setAttribute("Eintrag1", null);
            request.getSession().setAttribute("Eintrag2", null);
            request.getSession().setAttribute("Eintrag3", null);
            log.warn("die Session-Scope Attribute 'Eintrag1', 'Eintrag2' und 'Eintrag3' wurden" +
                    " vorsorglich auf null gesetzt, da sie noch vorher selektierte Items enthalten können");

            // ergebnisliste auslesen
            List list = (List) request.getSession().getAttribute("Ergebnisliste");
            int size = list.size();
            int aktuelleSeite = 1;
            int pages;
            int eintraegeAktuelleSeite;

            // für die anzeige der suchergebnisse notwendige atttribute berechnen
            if (size > 0) {
                boolean isLastPageComplete;
                if ((size % 3) == 0){
                    pages = size / 3;
                    isLastPageComplete = true;
                } else {
                    pages = (size / 3) + 1;
                    isLastPageComplete = false;
                }

                if ((aktuelleSeite == pages) && (!isLastPageComplete)) {
                    eintraegeAktuelleSeite = size % 3;
                } else {
                    eintraegeAktuelleSeite = 3;
                }

                log.warn("Größe der Ergebnisliste: " + size);
                log.warn("aktuelle Seite: " + aktuelleSeite);
                log.warn("Anzahl der Seiten: " + pages);
                log.warn("Ist die letzte Seite vollständig: " + isLastPageComplete);
                log.warn("Aktuelle Seite ist die letzte Seite ist:  " + (aktuelleSeite == pages));
                log.warn("Anzahl der Einträge auf der aktuellen Seite ist: " + eintraegeAktuelleSeite);

                // berechnete attribute im session scope ablegen (teil I)
                try {
                    while (eintraegeAktuelleSeite > 0) {
                        log.warn("initialisiereErgebnisAnzeigen(...): while-schleife zum Ablegen der" +
                                " ausgewaehlten Einträge im Session-Scope wird betreten");
                        request.getSession().setAttribute("Eintrag" + eintraegeAktuelleSeite, list.get((eintraegeAktuelleSeite - 1)
                                + ((aktuelleSeite - 1) * 3) ));
                        
                        // Beginn Logging-Code
                        Object o =(Object) request.getSession().getAttribute("Eintrag" + eintraegeAktuelleSeite);
                        log.warn("Klasse des im Session Scope abzulegenden Eintrages: " + o.getClass().getName());
                       
                        if (o.getClass().getName().equalsIgnoreCase("sopra09.lv6659438.objekte.Buch")) {
                            Buch b = (Buch) o;
                            log.warn("Eintrag" + eintraegeAktuelleSeite + ": typ=" + b.getTyp() + ", jahr=" + b.getJahr() 
                                    + ", titel=" + b.getTitel() + ", AnzahL Autoren=" + b.getAutoren().size());
                            int i = 1;
                            for (Autor a : b.getAutoren() ) {       
                               log.warn("Autor" + i + ": " + a.getName());
                               i++;
                            }   
                        } else if (o.getClass().getName().equalsIgnoreCase("sopra09.lv6659438.objekte.Zeitschrift")) {
                            Zeitschrift z = (Zeitschrift) o;
                            log.warn("Eintrag" + eintraegeAktuelleSeite + ": typ=" + z.getTyp() + ", titel=" + z.getTitel() +
                                     ", volumen=" + z.getVolumen() + ", nummer=" + z.getNummer());
                        }
                        // Ende Logging-Code


                        eintraegeAktuelleSeite--;
                    }
                } catch (ArrayIndexOutOfBoundsException a) {
                    a.toString();
                }

                // berechnete attribute im session scope ablegen (teil II)
                request.getSession().setAttribute("listengröße", size);
                request.getSession().setAttribute("seitenzahl", pages);
                request.getSession().setAttribute("aktuelleSeite",aktuelleSeite);
                request.getSession().setAttribute("letzteSeiteIstKomplett", isLastPageComplete);

                log.warn("die Session-Attribute wurden gesetzt.");
                log.warn("nach der Initialisierung wird an " +  mapping.findForward(ERGEBNIS_ANZEIGEN).getPath()
                        + " weitergeleitet.");

                return mapping.findForward(ERGEBNIS_ANZEIGEN);
             } else {
                log.warn("Größe der Ergebnisliste ist: " + size);
                return mapping.getInputForward();
             }
    }

    /**
     * Blättert in der Ergebnisliste eine Seite weiter, wenn der 'Weiter'-Button
     * gedrückt wurde.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
    public ActionForward weiter(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("weiter(...) beginnt");

        // benötigte attribute aus dem session scope auslesen
        List list = (List) request.getSession().getAttribute("Ergebnisliste");
        int eintraegeAktuelleSeite;
        int size = (Integer) request.getSession().getAttribute("listengröße");
        boolean isLastPageComplete = (Boolean) request.getSession().getAttribute("letzteSeiteIstKomplett");
        int seitenzahl = (Integer) request.getSession().getAttribute("seitenzahl");


        int aktuelleSeite = (Integer) request.getSession().getAttribute("aktuelleSeite");
        
        log.warn("Aktuelle Seite ist: " + aktuelleSeite);

        int seitePlusEins = aktuelleSeite + 1;

        log.warn("seitePlusEins ist: " + seitePlusEins);

        // anpassen der aktuellen seitenzahl
        if (seitePlusEins <= seitenzahl) {
            log.warn("(seitePlusEins <= seitenzahl) ist " + (seitePlusEins <= seitenzahl));
            log.warn("aktuelleSeite im Session-Scope wird um 1 erhöht");

            request.getSession().setAttribute("aktuelleSeite", seitePlusEins);

            log.warn("Aktuelle Seite im Session-Scope ist " + request.getSession().getAttribute("aktuelleSeite"));

         // fehlermeldung wenn letzte seite erreicht ist. dieser code dürfte nie
         // aufgerufen werden, da der 'weiter'-button auf der letzten ergebnisseite
         // deaktiviert wird.
        }else {
            log.warn("Da (seitePlusEins <= seitenzahl)" + (seitePlusEins <= seitenzahl) + " ist, " +
                    "ist die letzte Seite erreicht. Es wird an " +  mapping.getInputForward().getPath() + " weitergeleitet " +
                    "und eine Fehlermeldung ausgegeben.");

            ActionMessages fehler = new ActionMessages();
            fehler.add("letzteSeiteErreicht", new ActionMessage("fehlermeldung.letzteSeiteErreicht"));
            saveErrors(request, fehler);

            return mapping.getInputForward();
        }
    
        // berechnung der anzahl der ergebniseinträge auf der aktuellen seite
        if ((seitePlusEins == seitenzahl) && (!isLastPageComplete)) {
               log.warn("((seitePlusEins == seitenzahl) && (!isLastPageComplete)) ist " +
                       ((seitePlusEins == seitenzahl) && (!isLastPageComplete)));
                eintraegeAktuelleSeite = (size % 3);
                log.warn("die aktuelle Seite ist die letzte Seite und hat: "
                        + eintraegeAktuelleSeite + " Einträge.");
            } else {
                eintraegeAktuelleSeite = 3;
                log.warn("die aktuelle Seite hat: "
                        + eintraegeAktuelleSeite + " Einträge.");
       }

        // aufräumen des session scopes
        log.warn("Einträge im Session-Scope zurücksetzen.");
        request.getSession().setAttribute("Eintrag1", null);
        request.getSession().setAttribute("Eintrag2", null);
        request.getSession().setAttribute("Eintrag3", null);
        log.warn("Eintrag1 ist: " + request.getSession().getAttribute("Eintrag1"));
        log.warn("Eintrag2 ist: " + request.getSession().getAttribute("Eintrag2"));
        log.warn("Eintrag3 ist: " + request.getSession().getAttribute("Eintrag3"));

        // den session scope attributen werden neue werte zugewiesen
        try {
        while (eintraegeAktuelleSeite > 0) {
                log.warn("while-schleife zum Setzen der Session-Attribute der Ergebnisliste " +
                        "wird betreten.");
                log.warn("aktuelleSeite ist: " + request.getSession().getAttribute("aktuelleSeite"));
                log.warn("eintraegeAktuelleSeite ist: " + eintraegeAktuelleSeite);
                log.warn("Der Index des anzuzeigenden Literatureintrages wird berechnet als: \n" +
                        "((eintraegeAktuelleSeite + ((aktuelleSeite - 1) * 3)) - 1) ist: " +
                        ((eintraegeAktuelleSeite +  (((Integer)(request.getSession().getAttribute("aktuelleSeite"))) - 1) * 3) - 1) );

                request.getSession().setAttribute("Eintrag" + eintraegeAktuelleSeite,
                        list.get(((eintraegeAktuelleSeite +  (((Integer)(request.getSession().getAttribute("aktuelleSeite"))) - 1) * 3)- 1 )));

                eintraegeAktuelleSeite--;
            }
        } catch (ArrayIndexOutOfBoundsException a) {
            a.toString();
        }
            log.warn("die Session-Attribute wurden gesetzt.");
            log.warn("nach der Initialisierung wird an " +  mapping.findForward(ERGEBNIS_ANZEIGEN).getPath()
                    + " weitergeleitet.");


        return mapping.findForward(ERGEBNIS_ANZEIGEN);
    }

    /**
     * Blättert in der Ergebnisliste eine Seite zurück, wenn der 'Zurück'-Button
     * gedrückt wurde.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
    public ActionForward zurueck(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        log.warn("zurueck(...) beginnt");

        // attribute aus dem session scope auslesen
        List list = (List) request.getSession().getAttribute("Ergebnisliste");
        int eintraegeAktuelleSeite;

        int aktuelleSeite = (Integer) request.getSession().getAttribute("aktuelleSeite");

        log.warn("Aktuelle Seite ist: " + aktuelleSeite);

        int seiteMinusEins = aktuelleSeite - 1;

        log.warn("seiteMinusEins ist: " + seiteMinusEins);

         // anpassen der aktuellen seitenzahl
        if (seiteMinusEins >= 1) {
            log.warn("(seiteMinusEins >= 1) ist " + (seiteMinusEins >= 1));
            log.warn("aktuelleSeite im Session-Scope wird um 1 vermindert");

            request.getSession().setAttribute("aktuelleSeite", seiteMinusEins);

            log.warn("Aktuelle Seite im Session-Scope ist " + request.getSession().getAttribute("aktuelleSeite"));

        // fehlermeldung wenn erste seite erreicht ist. dieser code dürfte nie
         // aufgerufen werden, da der 'zurück'-button auf der ersten ergebnisseite
         // deaktiviert wird.
        }else {
            log.warn("Da (seiteMinusEins < 1)" + (seiteMinusEins < 1) + " ist, " +
                    "ist die erste Seite erreicht. Es wird an " +  mapping.getInputForward().getPath() + " weitergeleitet " +
                    "und eine Fehlermeldung ausgegeben.");

            ActionMessages fehler = new ActionMessages();
            fehler.add("ersteSeiteErreicht", new ActionMessage("fehlermeldung.ersteSeiteErreicht"));
            saveErrors(request, fehler);

            return mapping.getInputForward();
        }

       eintraegeAktuelleSeite = 3;
       log.warn("die aktuelle Seite kann nicht die letzte Seite sein. Sie hat daher "
                        + eintraegeAktuelleSeite + " Einträge.");

        // aufräumen des session scopes
        log.warn("Einträge im Session-Scope zurücksetzen.");
        request.getSession().setAttribute("Eintrag1", null);
        request.getSession().setAttribute("Eintrag2", null);
        request.getSession().setAttribute("Eintrag3", null);
        log.warn("Eintrag1 ist: " + request.getSession().getAttribute("Eintrag1"));
        log.warn("Eintrag2 ist: " + request.getSession().getAttribute("Eintrag2"));
        log.warn("Eintrag3 ist: " + request.getSession().getAttribute("Eintrag3"));

        // den session scope attributen werden neue werte zugewiesen
        try {
        while (eintraegeAktuelleSeite > 0) {
                log.warn("while-schleife zum Setzen der Session-Attribute der Ergebnisliste " +
                        "wird betreten.");
                log.warn("aktuelleSeite ist: " + request.getSession().getAttribute("aktuelleSeite"));
                log.warn("eintraegeAktuelleSeite ist: " + eintraegeAktuelleSeite);
                log.warn("Der Index des anzuzeigenden Literatureintrages wird berechnet als: \n" +
                        "((eintraegeAktuelleSeite + ((aktuelleSeite - 1) * 3)) - 1) ist: " +
                        ((eintraegeAktuelleSeite +  (((Integer)(request.getSession().getAttribute("aktuelleSeite"))) - 1) * 3) - 1) );

                request.getSession().setAttribute("Eintrag" + eintraegeAktuelleSeite,
                        list.get(((eintraegeAktuelleSeite +  (((Integer)(request.getSession().getAttribute("aktuelleSeite"))) - 1) * 3)- 1 )));

                eintraegeAktuelleSeite--;
            }
        } catch (ArrayIndexOutOfBoundsException a) {
            a.toString();
        }
            log.warn("die Session-Attribute wurden gesetzt.");
            log.warn("nach der Initialisierung wird an " +  mapping.findForward(ERGEBNIS_ANZEIGEN).getPath()
                    + " weitergeleitet.");


        return mapping.findForward(ERGEBNIS_ANZEIGEN);       
    }

    /**
     * Verarbeitet das vom Nutzer in der Ergebnisliste ausgewählte Element.
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return ActionForward
     */
     public ActionForward verarbeiteAuswahl(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.warn("verarbeiteAuswahl(...) beginnt");

        ItemSelektierenAF af = (ItemSelektierenAF) form;     

        // das vom nutzer ausgewählte item auslesen
        String auswahl = af.getAuswahl();
        if (auswahl == null) {
             log.warn("Da auswahl " + auswahl + " ist, " +
                    "wird an " +  mapping.getInputForward().getPath() + " weitergeleitet " +
                    "und eine Fehlermeldung ausgegeben.");

            ActionMessages fehler = new ActionMessages();
            fehler.add("keinItemSelektiert", new ActionMessage("fehlermeldung.keinItemSelektiert"));
            saveErrors(request, fehler);

            return mapping.getInputForward();
        } else {
        log.warn("das ausgewählte Item ist: " + auswahl);

        // das ausgewählte item im session scope ablegen
        request.getSession().setAttribute("selektiertesItem", auswahl);

        // da in diesem projekt 'eintrag auswaehlen' nur von einem übergeordneten
        // anwendungsfall benutzt wird, wird direkt an 'eintrag loeschen'
        // zurückgeleitet. in einem größeren system wäre ein stack zu implementieren,
        // auf dem der jeweils zuletzt aufrufende awf abgelegt wird und von dem er
        // nach der auswahl eines items wieder heruntergenommen wird.
        return mapping.findForward(SELEKTIERTEN_EINTRAG_LOESCHEN);
        }
    }

   
    public ActionForward zeigeZuAenderndeSuchkriterienAn(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        return mapping.findForward(SUCHKRITERIEN_EINGEBEN_ANZEIGEN);
    }

}
